#include "Bsp_DMA_M_P.h"


char txBuffer[BUFFER_SIZE];  // 用于存储待发送的数据

void DMA_M_P_Init(void)
{
    // 启动 DMA 时钟（DMA2 总线时钟）
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

    DMA_InitTypeDef DMA_InitStruct;

    // 配置 DMA 通道  通道 5  流 6
    DMA_InitStruct.DMA_Channel = DMA_Channel_5;  // USART6 使用 DMA2 流6，通道5

    // 配置 DMA 模式   正常
    DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;

    // 配置 DMA 优先级   高
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;

    // 配置 FIFO 模式   禁用 FIFO
    DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;

    // 配置 FIFO 阈值   FIFO 已禁用  不用设置
    DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

    // 设置外设和内存的基地址
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&USART6->DR;
    DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)txBuffer;

    // 设置地址增量（外设地址不递增,内存地址递增）
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;               

    // 设置数据大小    字节
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    // 设置数据传输方向  M to P
    DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;

    // 设置数据传输的大小
    DMA_InitStruct.DMA_BufferSize = BUFFER_SIZE;

    // 设置内存和外设的突发模式
    DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    // 初始化 DMA 配置
    DMA_Init(DMA2_Stream6, &DMA_InitStruct);

    // 使能 DMA 流
    DMA_Cmd(DMA2_Stream6, ENABLE);

    // 使能串口和DMA
    USART_DMACmd(USART6, USART_DMAReq_Tx, ENABLE);
}

void DMA_M_P_NVIC_Init(void)
{
    // 启用 DMA 传输完成中断
    DMA_ITConfig(DMA2_Stream6, DMA_IT_TC, ENABLE);

    // 配置 DMA 中断优先级
    NVIC_InitTypeDef NVIC_InitStruct;

    NVIC_InitStruct.NVIC_IRQChannel = DMA2_Stream6_IRQn;  // DMA2 流6中断
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;  // 优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;         // 子优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            // 使能中断

    NVIC_Init(&NVIC_InitStruct);
}

// DMA2 流6中断服务函数
void DMA2_Stream6_IRQHandler(void)
{
    // 检查 DMA 完成标志
    if (DMA_GetITStatus(DMA2_Stream6, DMA_IT_TCIF6))
    {
        // 清除 DMA 完成中断标志
        DMA_ClearITPendingBit(DMA2_Stream6, DMA_IT_TCIF6);

        // 打印信息，表示数据发送完成
        printf("txBuffer=%s",txBuffer);

    }
}
